home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-04
/
pxewin.zip
/
DBDISPLY.CPP
< prev
next >
Wrap
Text File
|
1992-02-17
|
17KB
|
664 lines
// PXEWIN - (C) Copyright 1992 by Beam Engineering, INC.
// DBDISPLY_CPP //
// Contents ----------------------------------------------------------------
//
// This header contains members for the DBDISPLAY class.
//
// End ---------------------------------------------------------------------
// External Reference Name For This Header ---------------------------------
#ifndef DBDISPLY_CPP
#define DBDISPLY_CPP
// End ---------------------------------------------------------------------
// Interface Dependencies --------------------------------------------------
#ifndef DBDISPLY_HPP
#include "dbdisply.hpp"
#endif // DBDISPLY_HPP //
#ifndef PXLISTBX_CPP
#include "pxlistbx.cpp"
#endif // PXLISTBX_CPP //
#ifndef BROWSE_HPP
#include "browse.hpp"
#endif // BROWSE_HPP //
// End ---------------------------------------------------------------------
// constructor DBDISPLAY //
inline DBDISPLAY::DBDISPLAY()
{
my_parm = NULL;
UpdateFlag = 1;
// Set your engine object pointer to this
EngDataPtr->PXEObjPtr = this;
top_rec = 1;
item = 0;
field = 0;
}
// Description -------------------------------------------------------------
//
// Constructor for DBDISPLAY. Set my_parm to NULL, UpdateFlag for
// display updates, set the EngDataPtr to this object since it will
// be the parent object, top_rec to first record, item to first item
// in the list box. field is the first field in the record.
//
// End ---------------------------------------------------------------------
// member build of DBDISPLAY //
PTStreamable DBDISPLAY::build()
{
return new DBDISPLAY(streamableInit);
}
TStreamableClass RegDBDISPLAY("DBDISPLAY",DBDISPLAY::build,
__DELTA(DBDISPLAY));
// Description -------------------------------------------------------------
//
// When the streamable constructor is called, TStreamable dispatches
// the build member to construct the object. To do this, it must
// know where to find this member functions for the specific class.
// This is the reason for the stream registration.
//
// End ---------------------------------------------------------------------
// member read of DBDISPLAY //
inline Pvoid DBDISPLAY::read(Ripstream is)
{
PXDIS::read(is);
my_parm = NULL;
UpdateFlag = 1;
// Set your engine object pointer to this
EngDataPtr->PXEObjPtr = this;
is >> (RECORDNUMBER)top_rec >> item;
return this;
}
// Summary -----------------------------------------------------------------
//
// Read this object off the stream.
//
// Parameters
//
// is. The incomming stream.
//
// Return Value
//
// Returns this objects pointer.
//
// Functional Description
//
// 1. Call base class reader.
// 2. Intialize as you would in the constructor.
// 3. Get the top_rec and item off the stream.
//
// End ---------------------------------------------------------------------
// member write of DBDISPLAY //
inline void DBDISPLAY::write(Ropstream os)
{
PXDIS::write(os);
os << (RECORDNUMBER)top_rec << item;
}
// Summary -----------------------------------------------------------------
//
// Write top_rec and item to the stream.
//
// End ---------------------------------------------------------------------
// member FillBoxes //
void DBDISPLAY::FillBoxes(RECORDNUMBER rec)
{
int i; /* Field index */
int j; /* Record index */
int sel; /* Temperary item selection
variable */
int upper_limit; /* Number of records to
get */
Pchar temp;
// Set mouse cursor to wait
SendMessage(AP->Parent->HWindow,WM_SETWTCUR,0,0);
// Reset update flag
UpdateFlag = 0;
// Check and see if record number is less than first record.
if(rec < 1)
rec = 1;
// Get the number of records in the table.
my_table->NumRecs();
// If you have less records then a PAGE_SIZE, then set your first
// record of the page to the first record in the database. Set the
// upper limit of the last record you will get to the number of
// records in the database.
if(EngDataPtr->num_recs < PAGE_SIZE)
{
upper_limit = EngDataPtr->num_recs;
top_rec = 1;
}
else
{
// Else, set the upper limit to the page size.
upper_limit = PAGE_SIZE;
// If you are less than a page size away from the end of the
// database, set the top record to the number of records in
// the database minus the size of the page.
if(rec + PAGE_SIZE > EngDataPtr->num_recs){
top_rec = EngDataPtr->num_recs - PAGE_SIZE + 1;
sel = rec - top_rec;
}
else
{
// Else, leave the top record value at the parameter
// setting.
top_rec = rec;
sel = item;
}
}
// Empty the list boxes.
for(i = 0;i < EngDataPtr->num_fields;i++)
my_parm[i]->my_box->ClearList();
my_record->GoTo(top_rec);
for(j = 0;j < upper_limit;j++)
{
// Get the record data into the record transfer buffer.
my_record->Get();
for(i = 0;i < EngDataPtr->num_fields;i++)
{
// Get the field data and put in into the list box.
temp = PXDIS::Get(i);
my_parm[i]->my_box->AddString(temp);
}
// Go to the next record.
my_record->RecNext();
}
// Set item out of bounds so it will pass through range check ok
item = -1;
// Set update flag
UpdateFlag = 1;
// Select the item
SelRecord(sel);
// Set mouse cursor to normal
SendMessage(AP->Parent->HWindow,WM_SETNMCUR,0,0);
}
// Summary -----------------------------------------------------------------
//
// This member fills the list boxes with data from the database.
//
// Parameters
//
// rec. This is the record number of the top record in the list boxes.
//
// Return Value
//
// None.
//
// Functional Description
//
// 1. Set the mouse cursor to the wait cursor.
//
// 2. Reset the UpdateFlag so updates will not occur until the list
// boxes are refilled. This flag will be read by the PXListBox
// routine to make sure Updates as they would normally when WMPaint is
// called (TControl version of WMPaint).
//
// 3. Range check rec. If it is less than the first record, reset it
// to the first record. For a table that is less the a PAGE_SIZE, limit
// the upperbound accordingly. Else the upperbound is the PAGE_SIZE.
// If rec plus PAGE_SIZE is greater than the number of records then set
// top_rec to PAGE_SIZE less than the number of records and your
// selection is somewhere in between. Else leave rec untouched and
// set you selection to the top record.
//
// 4. Empty the list boxes.
//
// 5. Fill the list boxes.
//
// 6. You need to set the item number out of bounds so the selection
// routine sees that the selection has changed.
//
// 7. Set the UpdateFlag to allow updates and call the selection
// routine.
//
// 8. Set the mouse cursor to normal.
//
// End ---------------------------------------------------------------------
// member SetUp //
int DBDISPLAY::SetUp(PBrowser AParent)
{
Pchar header; /* Temp location for header
*/
int hd_len; /* Length of header */
int char_size; /* Is the number of ASCII
characters it takes to
represent the field. */
int i; /* Field index */
HDC hdc; /* Window device context */
char szFaceName[LF_FACESIZE]; /* Recieves current fonts
name */
TEXTMETRIC tm; /* Data structure for font
info. */
EngDataPtr->name = AParent->name;
AP = AParent;
sum = 1;
// Get a context handle in the current window.
hdc = GetDC(AParent->HWindow);
// This will get the name of the type face into the face name array
GetTextFace(hdc,sizeof(szFaceName),szFaceName);
// Load the data structure with the font info.
GetTextMetrics(hdc,&tm);
// We will set the character width to the maximum size just to
// be on the safe side.
char_width = tm.tmMaxCharWidth;
// Release the handle so you don't run out of handles.
ReleaseDC(AParent->HWindow,hdc);
// Setup database
PXDIS::SetUp(0,0,EXISTS,0);
if(EngDataPtr->Errors.pxerr != PXSUCCESS)
return EngDataPtr->Errors.pxerr;
// Make an array of field parameter pointers
my_parm = new PLB_PARM [EngDataPtr->num_fields];
for(i = 0;i < EngDataPtr->num_fields;i++){
my_parm[i] = new LB_PARM;
// Set up a field pointer
my_parm[i]->my_field = my_field[i];
// If parameter set is the first set, initialize x
// coordinate of the list box independently.
if(i == 0)
my_parm[i]->x = 2;
else{
// Else, the list box coordinate depends on
// where the previous list box ends.
my_parm[i]->x = my_parm[i - 1]->x +
my_parm[i - 1]->w + 2;
}
// Precalc some things we will be using more than once.
header = my_parm[i]->my_field->RetName();
hd_len = strlen(header);
char_size = my_parm[i]->my_field->RetCharSize();
// The width of the list box is calculated. It is
// the character size of the field times the
// character width unless the field header is larger.
if(char_size > hd_len){
my_parm[i]->w = char_size*char_width;
sum += char_size;
}
else{
my_parm[i]->w = hd_len*char_width;
sum += hd_len;
}
// Set up the list box.
my_parm[i]->my_box = new PXListBox(AParent,i,
my_parm[i]->x,20,my_parm[i]->w,16.5*PAGE_SIZE);
// Set up header for your list boxes
my_parm[i]->my_header = new TStatic(AParent,-1,
header,my_parm[i]->x,1,200,15,hd_len + 1);
}
return PXSUCCESS;
}
// Summary -----------------------------------------------------------------
//
// This sets up the database for displaying all the fields.
//
// Parameters
//
// AParent. Needs the parent window object to construct the list boxes
// and the field headers.
//
// Functional Description
//
// 1. Call the SetUp routine for setting up the database.
//
// 2. Construct a parameter array for storing list box info.
//
// 3. Construct a for loop that will initialize all the fields for
// display. The information necessary for storing the list box data is
// saved in the LB_PARM structure. Placement locations and sizes of
// each list box are calculated. Headers for each field are placed
// at the top of the list box.
//
// End ---------------------------------------------------------------------
// Destructor ~DBDISPLAY //
DBDISPLAY::~DBDISPLAY()
{
int i; /* Field index */
// if ther is no parameter pointer, then the number of fields is
// unknown so set to zero.
if(!my_parm)
EngDataPtr->num_fields = 0;
for(i = 0;i < EngDataPtr->num_fields;i++)
delete my_parm[i];
delete my_parm;
}
// End ---------------------------------------------------------------------
// Summary -----------------------------------------------------------------
//
// Kills all buffers used in DBDISPLAY.
//
// End ---------------------------------------------------------------------
// member SelRecord //
void DBDISPLAY::SelRecord(int ITEM)
{
int i; /* Field index */
// Range check item
if(ITEM >= PAGE_SIZE)
ITEM = PAGE_SIZE - 1;
if(ITEM < 0)
ITEM = 0;
if(item == ITEM)
{
if(item == 0)
ScrollDwn();
else{
if(item == PAGE_SIZE - 1)
ScrollUp();
}
}
// Select items if you are somewhere within a page or your have
// incremented past the page but you are not at the last record.
// For a decrement before the page you don't need to select since
// you are doing and insert at the first record.
if((item == PAGE_SIZE - 1) || item != ITEM)
{
for(i = 0;i < EngDataPtr->num_fields;i++)
{
my_parm[i]->my_box->SetSelIndex(ITEM);
}
}
item = ITEM;
}
// Summary -----------------------------------------------------------------
//
// Selects the record cooresponding to the item number in the list boxes
//
// Parameters
//
// item. This is the list box item number.
//
// Return Value
//
// None.
//
// Description
//
// 1. The item number is range checked. If the item number is greater
// then the page size then it is set to the page size. If the item
// number is less than the first item number, it is set to the first
// item.
//
// 2. If the old item number is equal to the new item number then check
// for a scroll up or down situation. It is scroll up if item is the
// first item, scroll down if item is the last item in the list box.
//
// 3. If item selected is at the end of the list or somewhere in
// the middle of the list, then set all the lists to the same item.
//
// End ---------------------------------------------------------------------
// member IncRec of DBDISPLAY //
void DBDISPLAY::IncRec()
{
SelRecord(item + 1);
}
// Summary -----------------------------------------------------------------
//
// Increments an item in the list boxes.
//
// End ---------------------------------------------------------------------
// member DecRec of DBDISPLAY //
void DBDISPLAY::DecRec()
{
SelRecord(item - 1);
}
// Summary -----------------------------------------------------------------
//
// Decrements an item in the list boxes.
//
// End ---------------------------------------------------------------------
// member ScrollUp //
void DBDISPLAY::ScrollUp()
{
int i; /* Field index */
// Make sure your not already at the last record in the table.
// Note that we specifically call for the number of records since
// this may change as we add and delete records from the database.
my_table->NumRecs();
if(top_rec + PAGE_SIZE <= EngDataPtr->num_recs){
// Go to the new record and get data
my_record->GoTo(top_rec + PAGE_SIZE);
my_record->Get();
for(i = 0;i < EngDataPtr->num_fields;i++)
{
// Delete the first item in the list
my_parm[i]->my_box->DeleteString(0);
// Add the new next item to the list
my_parm[i]->my_box->AddString(PXDIS::Get(i));
}
top_rec++;
}
}
// Summary -----------------------------------------------------------------
//
// This scrolls the display up by one record.
//
// Parameters
//
// None.
//
// Return Value
//
// None.
//
// Description
//
// 1. Do a boundary check and make sure your not at the last record.
//
// 2. Go to the last record in the list and get the data.
//
// 3. For all the lists, delete the first item in the list and add the
// new data to the end of the list.
//
// 4. Increment the top record pointer.
//
// End ---------------------------------------------------------------------
// member ScrollDwn //
void DBDISPLAY::ScrollDwn()
{
int i; /* Field index */
// Make sure your not already at the first record in the table
if(top_rec > 1){
// Go to the new record and get data
top_rec--;
my_record->GoTo(top_rec);
my_record->Get();
for(i = 0;i < EngDataPtr->num_fields;i++)
{
// Delete the last item in the list
my_parm[i]->my_box->DeleteString(PAGE_SIZE - 1);
// Add the new text item to the begining of the list
my_parm[i]->my_box->InsertString(PXDIS::Get(i),0);
}
}
}
// Summary -----------------------------------------------------------------
//
// Scrolls the display down one record.
//
// Parameters
//
// None.
//
// Return Value
//
// None.
//
// Description
//
// 1. Make sure you are not at the first record in the database.
//
// 2. Decrement the top record pointer.
//
// 3. Go to the top record and get the data.
//
// 4. For all the fields, delete the last string in the list and insert
// the new data at the first string position in the list.
//
// End ---------------------------------------------------------------------
// member PXError of DBDISPLAY //
inline void DBDISPLAY::PXError(int org)
{
// Call base class error handler.
PXEngObject::PXError(org);
// Send the PX Engine error message back to the parent window
if(EngDataPtr->Errors.pxerr != PXSUCCESS)
{
// Because you may have the display update flag reset so
// that no updates can occur while the list boxes are being
// updated, you should make sure it's set before you dispatch
// the message or Windows will eventually crash because of
// the inability to process message traffic!!!!
UpdateFlag = 1;
SendMessage(AP->Parent->HWindow,WM_PXERROR,0,0);
}
}
// Summary -----------------------------------------------------------------
//
// If you get an error, send a message back to the parent window. This
// will dispatch all PDOX errors back to the parent window.
//
// End ---------------------------------------------------------------------
#endif // DBDISPLY_CPP //